<template>
  <div style="width: 100%; height: 100%"></div>
</template>

<script>
import {
  Scene,
  PerspectiveCamera,
  WebGLRenderer,
  SpotLight,
  AmbientLight,
  Vector3,
  Geometry,
  LineBasicMaterial,
  VertexColors,
  Line,
  Color
} from 'three'
import Detector from 'three/examples/js/Detector'
export default {
  data() {
    return {
      scene: null,
      camera: null,
      renderer: null,
      ele: null,
      width: 0,
      height:0,
      line: null
    }
  },
  mounted() {
    this.ele = this.$el
    this.width = this.$el.clientWidth
    this.height = this.$el.clientHeight

    if (!Detector.webgl) {
      const warning = Detector.getWebGLErrorMessage()
      this.ele.appendChild(warning)
    }
    this.threeStart()
  },
  methods: {
    threeStart () {
      this.initThree()
      this.initScene()
      this.initCamera()
      this.initLight()
      this.addGeometry()
      this.render()
    },
    initThree () {
      this.renderer = new WebGLRenderer({
        antialias : true // 是否弱化锯齿特性，true表示弱化，更消耗cpu
      })
      this.renderer.setSize(this.width, this.height)
      this.ele.appendChild(this.renderer.domElement)
      this.renderer.setClearColor(0xEEEEEE, 1)
      this.renderer.shadowMap.enabled = false
    },
    initCamera () {
      this.camera = new PerspectiveCamera(45, this.width / this.height, 0.1, 1000)
      this.camera.position.set(-40, 40, 40)
      this.camera.lookAt(this.scene.position)
    },
    initScene () {
      this.scene = new Scene()
    },
    addGeometry () {
      const points = this.gosper(4, 60)

      const lines = new Geometry()
      let colors = []
      let i = 0
      points.forEach(function (e) {
        lines.vertices.push(new Vector3(e.x, e.y, e.z))
        colors[i] = new Color(0xffffff)
        colors[i].setHSL(e.x / 100 + 0.5, (e.y * 20) / 300, 0.8)
        i++
      })

      lines.colors = colors
      const material = new LineBasicMaterial({
        opacity: 1.0,
        linewidth: 1,
        vertexColors: VertexColors
      })

      this.line = new Line(lines, material)
      this.line.position.set(25, -30, -60)
      this.scene.add(this.line)
    },
    initLight () {
      const ambientLight = new AmbientLight(0x0c0c0c)
      this.scene.add(ambientLight)

      const spotLight = new SpotLight(0xffffff)
      spotLight.position.set(-40, 60, -10)
      spotLight.castShadow = true
      this.scene.add(spotLight)
    },
    gosper (a, b) {

      var turtle = [0, 0, 0]
      var points = []
      var count = 0

      rg(a, b, turtle)


      return points

      function rt (x) {
        turtle[2] += x
      }

      function lt (x) {
        turtle[2] -= x
      }

      function fd (dist) {
        //                ctx.beginPath();
        points.push({
          x: turtle[0],
          y: turtle[1],
          z: Math.sin(count) * 5
        })
        //                ctx.moveTo(turtle[0], turtle[1]);

        var dir = turtle[2] * (Math.PI / 180)
        turtle[0] += Math.cos(dir) * dist
        turtle[1] += Math.sin(dir) * dist

        points.push({
          x: turtle[0],
          y: turtle[1],
          z: Math.sin(count) * 5
        })
        //                ctx.lineTo(turtle[0], turtle[1]);
        //                ctx.stroke();
      }

      function rg (st, ln, turtle) {

        st--
        ln = ln / 2.6457
        if (st > 0) {
          //                    ctx.strokeStyle = '#111';
          rg(st, ln, turtle)
          rt(60)
          gl(st, ln, turtle)
          rt(120)
          gl(st, ln, turtle)
          lt(60)
          rg(st, ln, turtle)
          lt(120)
          rg(st, ln, turtle)
          rg(st, ln, turtle)
          lt(60)
          gl(st, ln, turtle)
          rt(60)
        }
        if (st == 0) {
          fd(ln)
          rt(60)
          fd(ln)
          rt(120)
          fd(ln)
          lt(60)
          fd(ln)
          lt(120)
          fd(ln)
          fd(ln)
          lt(60)
          fd(ln)
          rt(60)
        }
      }

      function gl(st, ln, turtle) {
        st--
        ln = ln / 2.6457

        if (st > 0) {
          //                    ctx.strokeStyle = '#555';
          lt(60)
          rg(st, ln, turtle)
          rt(60)
          gl(st, ln, turtle)
          gl(st, ln, turtle)
          rt(120)
          gl(st, ln, turtle)
          rt(60)
          rg(st, ln, turtle)
          lt(120)
          rg(st, ln, turtle)
          lt(60)
          gl(st, ln, turtle)
        }

        if (st == 0) {
          lt(60)
          fd(ln)
          rt(60)
          fd(ln)
          fd(ln)
          rt(120)
          fd(ln)
          rt(60)
          fd(ln)
          lt(120)
          fd(ln)
          lt(60)
          fd(ln)
        }
      }
    },
    render () {
      this.line.rotation.z += 0.01
      requestAnimationFrame(this.render)
      this.renderer.render(this.scene, this.camera)
    }
  }
}
</script>
